package com.shoes.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.shoes.dao.UserDAO;
import com.shoes.model.UserDO;
import com.shoes.utils.AES;
import com.shoes.utils.LoggerUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.UnsupportedEncodingException;

/**
 * @author asen
 */
@Service("loginManager")
public class LoginManager {

    private UserDAO userDAO;

    public static final int EXPIREDAYS = 14;				//Token的过期时间
    public static final String USER_ID = "user_id";
    public static final String DEVICE_TYPE = "device_type";
    public static final String DIVIDE_CHAR = ":";

    /** 初始化加密参数 用于token的加密解密 */
    static {
        byte[] ivbyte = { 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32,
                0x31, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31 };
        AES.setSecret("a!g(201#co'e,e*f");					//设置密钥
        AES.setIv(ivbyte);									//设置CBC模式的向量
        try {
            AES.setCharset("UTF-8");						//设置字符编码
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    /**
     * 生成Token 针对手机登录
     * 		Token: current time + DIVIDE_CHAR + password + user_id
     */
    public String getToken(long userId) {
        String token;
        String password = null;
        try {
            password = userDAO.queryPasswordByUserId(userId);
        } catch (Exception e) {
            e.printStackTrace();
        }
        token = AES.encrypt(System.currentTimeMillis() + DIVIDE_CHAR + password + "&" + userId);
        return token;
    }

    /**
     * 验证Token 针对手机登录时的token登录
     * 		1、是否过期
     * 		2、是否相同
     */
    public boolean isTokenValid(long userID, String clientToken) {
        boolean result = false;

        if(userID <= 0) {
            return false;
        }

        if(clientToken == null || "".equals(clientToken) || "null".equals(clientToken)) {
            return false;
        }

        /** 获取生成token时的时间 */
        long generatedTime = 0;
        try{
            /** 解密token */
            String decryptedClientToken = AES.decrypt(clientToken);
            LoggerUtil.logger.info("client token :" + decryptedClientToken);
            if(decryptedClientToken != null) {
                generatedTime = Long.parseLong(decryptedClientToken.split(DIVIDE_CHAR)[0]);
            } else {
                LoggerUtil.logger.info("decryptedClientToken is null");
            }
        } catch (NumberFormatException e) {
            e.printStackTrace();
            return false;
        }

        /** 判断token是否过期 */
        if(generatedTime + EXPIREDAYS*24*60*60*1000 > System.currentTimeMillis()) {
            try {
                /** 获取服务器保存的token */
                String serveSavedToken = userDAO.queryLoginTokenByUserId(userID);
                LoggerUtil.logger.info(" serve token:" + serveSavedToken);
                if(clientToken.equals(serveSavedToken)) {
                    result = true;
                }
            } catch (Exception e) {
                return false;
            }
        }
        return result;
    }

    /**
     * 登入成功后处理
     * 		1、生成Token
     * 		2、生成session保存登录信息
     * 		3、使该用户之前的登录失效(Token已更新、只要是之前的session过去即可)
     * 		4、获取用户设备类型并更新用户的设备类型
     * @return Token
     */
    public String processAfterLogin(HttpServletRequest request, long userId, boolean isPhone, boolean isRegister) {
        /** 将生成的token保存在数据库中 */
        String token = null;
        if(isPhone) {
            UserDO user = new UserDO();
            token = getToken(userId);
            user.setUserId(userId);
            user.setToken(token);
            try {
                userDAO.updateUserInfo(user);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        /** 生成session 并保存user_id */
        HttpSession session = request.getSession(true);
        session.setAttribute("user_id", String.valueOf(userId));

        // TODO 处理重复登录问题
        if(!isRegister) {

        }
        return token;
    }

    /** 登出成功后处理
     * @throws Exception */
    public void processAfterLoginOut(HttpServletRequest request, long userId) {
        /** 使之对应的session失效*/
        HttpSession session = request.getSession(false);
        if(session != null) {
            session.invalidate();
        }

        /** 设置设备类型为null */
        try {
            userDAO.updateDeviceTypeToNull(userId);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /** 活动登录返回的JSON数据 */
    public JSONObject getLoginJSONData(long userId, String token) {
        JSONObject data = new JSONObject();
        UserDO user = null;
        try {
            user = userDAO.queryUserInfoById(userId);
        } catch (Exception e) {
            e.printStackTrace();
        }

        if(user != null) {
            data = JSON.parseObject(JSON.toJSONString(user));
        }
        data.put("user_id", userId);
        data.put("token", token);
        return data;
    }

    public UserDAO getUserDAO() {
        return userDAO;
    }
    @Autowired
    public void setUserDAO(UserDAO userDAO) {
        this.userDAO = userDAO;
    }
}
